<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

namespace App\Exception\Handler;

use App\Exception\BusinessException;
use Hyperf\Codec\Json;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpServer\Contract\RequestInterface;
use Mine\Log\RequestIdHolder;
use Mine\MineRequest;
use Psr\Http\Message\ResponseInterface;
use Sentry\ClientBuilder;
use Sentry\Spool\MemorySpool;
use Sentry\State\Hub;
use Sentry\Transport\SpoolTransport;
use Throwable;
use Hyperf\HttpServer\Contract\ResponseInterface as httpResponse;

class BusinessExceptionHandler extends ExceptionHandler
{
    /**
     * @var StdoutLoggerInterface
     */
    protected $logger;

    /**
     * @Inject()
     * @var httpResponse
     */
    protected $httpResponse;

    /**
     * @Inject
     * @var RequestInterface
     */
    protected $request;

    public function __construct(StdoutLoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function handle(Throwable $throwable, ResponseInterface $response)
    {

        if ($throwable instanceof BusinessException) {
            // 阻止异常冒泡
            $this->stopPropagation();
            $format = [
                'requestId' => RequestIdHolder::getId(),
                'path' => container()->get(MineRequest::class)->getUri()->getPath(),
                'success' => false,
                'code' => $throwable -> getCode(),
                'message' => $throwable->getMessage(),
            ];
            return $response->withHeader('Server', 'MineAdmin')
                ->withHeader('Access-Control-Allow-Origin', '*')
                ->withHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
                ->withHeader('Access-Control-Allow-Credentials', 'true')
                ->withHeader('Access-Control-Allow-Headers', 'accept-language,authorization,lang,uid,token,Keep-Alive,User-Agent,Cache-Control,Content-Type')
                ->withAddedHeader('content-type', 'application/json; charset=utf-8')
                ->withStatus($throwable -> getCode())->withBody(new SwooleStream(Json::encode($format)));
        }
        return $response;
    }

    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}
